#ifndef NET_TCPCONNECTION_H
#define NET_TCPCONNECTION_H

#include "Buffer.h"
#include "Callbacks.h"
#include "InetAddress.h"

class Channel;
class EventLoop;
class Socket;

extern void defaultConnectionCallback(const TcpConnectionPtr& conn);
extern void defaultMessageCallback(const TcpConnectionPtr&,
	Buffer* buf,
	Timestamp);

/// TCP connection, for both client and server usage.
//负责管理建立连接以后的connfd,注册connfd上的各种poll事件的回调函数
class TcpConnection : public std::enable_shared_from_this<TcpConnection>
{
public:
	/// Constructs a TcpConnection with a connected sockfd
	///
	/// User should not create this object.
	TcpConnection(EventLoop* loop,
			const std::string& name,
			int sockfd,
			const InetAddress& localAddr,
			const InetAddress& peerAddr);
	~TcpConnection();
	
	EventLoop* getLoop()const {return m_pLoop;}
	const std::string& name() const { return m_strName; }
	const InetAddress& localAddress() { return m_localAddr; }
	const InetAddress& peerAddress() { return m_peerAddr; }
	bool connected() const { return m_state == kConnected; }
	//Thread safe
	void send(const std::string& message);
	void send(Buffer* buf);
	void send(const void* data, size_t len);
	//Thread safe
	void shutdown();
	//保证在IO线程调用
	void sendInLoop(const std::string& message);
	void sendInLoop(const void* data, size_t len);
	void shutdownInLoop();
	void forceClose();

	void setConnCallback(ConnectionCallback cb){ m_connCallback = cb; }
	void setMsgCallback(MessageCallback cb){ m_msgCallback = cb; }
	//设置成功发完数据执行的回调
	void setWriteCompleteCallback(const WriteCompleteCallback& cb)
	{
		m_writeCompleteCallback = cb;
	}

	void setHighWaterMarkCallback(const HighWaterMarkCallback& cb, size_t highWaterMark)
	{
		m_highWaterMarkCallback = cb; m_highWaterMark = highWaterMark;
	}
	/// Internal use only.for TcpServe and TcpClient
	void setCloseCallback(const CloseCallback& cb){ m_closeCallback = cb;}
	// called when TcpServer accepts a new connection
	void connectEstablished();   // should be called only once
	// called when TcpServer has removed me from its map
	void connectDestroyed();  // should be called only once
	void setTcpNoDelay(bool on);
	void startRead();
	void startReadInLoop();
	void stopRead();
	void stopReadInLoop();
	/// Advanced interface
	Buffer* inputBuffer()
	{
		return &m_inputBuffer;
	}

	Buffer* outputBuffer()
	{
		return &m_outputBuffer;
	}
private:
	//kConnection:未连接，kConnected：已连接，kDisconnecting：shutDown办关闭，kDisconnected:已关闭
	//这四个连接状态可以在ConnectionCallback函数中监听TcpConnection,打印连接信息
	enum StateE { kConnecting, kConnected, kDisconnecting, kDisconnected};
	
	void setState(StateE s){ m_state = s; }
	void handleRead(Timestamp receiveTime);
	void handleWrite();
	void handleClose();
	void handleError();
	void forceCloseInLoop();

	EventLoop*					m_pLoop;
	std::string					m_strName;
	StateE						m_state;
	bool						m_bReading;
	// we don't expose those classes to client.
	std::unique_ptr<Socket>		m_pSocket;
	std::unique_ptr<Channel>	m_pChannel;
	InetAddress					m_localAddr;
	InetAddress					m_peerAddr;
	ConnectionCallback			m_connCallback;
	MessageCallback				m_msgCallback;
	WriteCompleteCallback		m_writeCompleteCallback;
	HighWaterMarkCallback		m_highWaterMarkCallback;
	CloseCallback				m_closeCallback;
	size_t						m_highWaterMark;
	Buffer						m_inputBuffer;
	Buffer						m_outputBuffer;
};
#endif //NET_TCPCONNECTION_H